package model

import state.ActionState
import game.Player
import java.util.ArrayList
import util.safeAdd

abstract class Card(val cost: Int) {
    val name = this.javaClass.getName()
    fun toString(): String = name
}

abstract class TreasureCard(cost: Int, val coins: Int): Card(cost)
object cooper: TreasureCard(0, 1)
object silver: TreasureCard(3, 2)
object gold: TreasureCard(6, 3)

abstract class VictoryCard(cost: Int, val victoryPoints: Int = 0): Card(cost)
object estate: VictoryCard(2, 1)
object duchy: VictoryCard(5, 3)
object province: VictoryCard(8, 6)
object gardens: VictoryCard(4)
object curse: VictoryCard(0, -1)

abstract class ActionCard(cost: Int,
                           val extraCard: Int = 0,
                           val extraAction: Int = 0,
                           val extraBuy: Int = 0,
                           val extraCoins: Int = 0): Card(cost) {

    open fun createActionState() = ActionState(this)
}
object adventurer: ActionCard(6)
object bureaucrat: ActionCard(4)
object cellar: ActionCard(2, extraAction = 1) {
    override fun createActionState() = object: ActionState(this) {
        override fun getMenu(g: Game, p: Player) = Menu("Discard any number of model: ", p.hand, true, true)

        override fun apply(g: Game, p: Player, selection: List<Card>) {
            with(p) {
                selection.forEach {
                    if (hand.remove(it)) {
                        playingArea.add(it)
                        hand.safeAdd(nextCard())
                    }
                }
            }
        }
    }
}
object chancellor: ActionCard(3, extraCoins = 2)
object chapel: ActionCard(2)
object councilRoom: ActionCard(5, extraCard = 4, extraBuy = 1)
object feast: ActionCard(4)
object festival: ActionCard(5, extraAction = 2, extraBuy = 1, extraCoins = 2)
object laboratory: ActionCard(5, extraCard = 2, extraAction = 1)
object library: ActionCard(5)
object market: ActionCard(5, 1, 1, 1, 1)
object militia: ActionCard(4, extraCoins = 2)
object mine: ActionCard(5)
object moat: ActionCard(2, extraCard = 2)
object moneyLender: ActionCard(4)
object remodel: ActionCard(4)
object smithy: ActionCard(4, extraCard = 3)
object spy: ActionCard(4, extraCard = 1, extraAction = 1)
object thief: ActionCard(4)
object throneRoom: ActionCard(4)
object village: ActionCard(3, extraCard = 1, extraAction = 2)
object witch: ActionCard(5, extraCard = 2)
object woodcutter: ActionCard(3, extraBuy = 1, extraCoins = 2)
object workshop: ActionCard(3) {
    override fun createActionState() = object: ActionState(this) {
        override fun getMenu(g: Game, p: Player): Menu? {
            val availableToGain = ArrayList<Card>()
            g.kingdom.values().forEach {
                val card = it.peek()
                if (card != null) availableToGain.add(card)
            }
            Menu("Gain a card costing up to 4: ", availableToGain, true)
        }

        override fun apply(g: Game, p: Player, selection: List<Card>) {
            if (selection.size() > 0) {
                p.playingArea.safeAdd(g.kingdom[selection.get(0)]!!.pop())
            }
        }
    }
}

val allKingdomCards = listOf(adventurer, bureaucrat, cellar, chancellor, chapel, councilRoom, feast, festival,
        laboratory, library, market, militia, mine, moat, moneyLender, remodel, smithy, spy, thief, throneRoom,
        village, witch, woodcutter, workshop)

val starterKingdomCards = listOf(village, smithy, woodcutter, workshop, militia, cellar, market, remodel, moat, mine)